package serveur;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import surname.protocol.AbstractRequest;
import surname.protocol.AddSurnameRequest;
import surname.protocol.EditSurnameRequest;
import surname.protocol.ListSurnameRequest;

public class Serveur 
{
	private ServerSocket socket = null;
	private Emission emission;
	private Reception reception;
	private Map<String, List<String>> annuaire;
	
	public Serveur()
	{
		annuaire=new HashMap<String, List<String>>();
		try 
		{
			System.out.println("Demarage du serveur");
			socket = new ServerSocket(6666);
			System.out.println("Serveur démarré");
		} 
		catch (IOException e) 
		{
			e.printStackTrace();
		}
		
		try 
		{	
				Socket socket2 = this.getSocket().accept();
				this.setR(new Reception(socket2));
				this.setE(new Emission(socket2));
		} 
		catch (IOException e) 
		{
			System.err.println("Plantage !");
		}
		
		while(true){
			
			AbstractRequest abstractReq = reception.get();
			
			if(abstractReq.getClass().equals(AddSurnameRequest.class)){
				
				System.out.println("AddSurnameRequest recue");
				
				AddSurnameRequest add=(AddSurnameRequest)abstractReq;
				
				System.out.println("nom : "+add.getName()+" surnom : "+add.getSurname());
				
				if(!containsSurname(add.getSurname())){
					
					if(annuaire.containsKey(add.getName())){
						
						annuaire.get(add.getName()).add(add.getSurname());
						
					} else {
						
						ArrayList<String> lis=new ArrayList<String>();
						lis.add(add.getSurname());
						annuaire.put(add.getName(), lis);
						
					}
				}
				
			} else if(abstractReq.getClass().equals(EditSurnameRequest.class)){
				
				System.out.println("EditSurnameRequest recue");
				
				EditSurnameRequest edit=(EditSurnameRequest)abstractReq;
				
				System.out.println("ancien surnom : "+edit.getOldSurname()+" surnom : "+edit.getNewSurname());
				
				editSurname(edit.getNewSurname(), edit.getOldSurname());
				
			} else if(abstractReq.getClass().equals(ListSurnameRequest.class)){
				
				System.out.println("ListSurnameRequest recue");
				
				printServer();
				
				ListSurnameRequest list=(ListSurnameRequest)abstractReq;
				
				list.setList(getListCopy());
				
				emission.send(list);
			}
		}
		
	}
	
	private boolean containsSurname(String surname){

		for(List<String>li : annuaire.values()){
			for(String s : li){
				if( s.equals(surname)){
					return true;
				}
			}
		}
		return false;
	}
	
	private void editSurname(String newSur, String oldSur){

		for(List<String>li : annuaire.values()){
			for(int i=0;i<li.size();i++){
				if( li.get(i).equals(oldSur)){
					li.set(i, newSur);
				}
			}
		}
	}

	public ServerSocket getSocket() {
		return socket;
	}

	public void setSocket(ServerSocket soc) {
		socket = soc;
	}

	public Emission getE() {
		return emission;
	}

	public void setE(Emission e) {
		this.emission = e;
	}

	public Reception getR() {
		return reception;
	}

	public  void setR(Reception r) {
		reception = r;
	}
	
	private void printServer(){
		for(String li : annuaire.keySet()){
			for(String ls:annuaire.get(li)){
				System.out.println(li+" : "+ ls);
			}
		}
	}
	
	public Map<String, List<String>> getListCopy ()
	   {
	       Map<String, List<String>> clist = new HashMap<String, List<String>>();

	       for (String key : annuaire.keySet())
	       {
	           List<String> csublist = new ArrayList<String>();

	           for (String surname : annuaire.get(key)){
	               csublist.add(new String(surname));
	           }

	           clist.put(key, csublist);
	       }

	       return clist;
	   }
	
}